{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# kNN 基础"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "raw_data_X = [\n",
    "    [3.393533211, 2.331273381],\n",
    "    [3.110073483, 1.781539638],\n",
    "    [1.343808831, 3.368360954],\n",
    "    [3.582294042, 4.679179110],\n",
    "    [2.280362439, 2.866990263],\n",
    "    [7.423436942, 4.696522875],\n",
    "    [5.745051997, 3.533989803],\n",
    "    [9.172168622, 2.511101045],\n",
    "    [7.792783481, 3.424088941],\n",
    "    [7.939820817, 0.791637231]\n",
    "]  # 两列分别代表肿瘤的长和宽\n",
    "raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] # 0是良性肿瘤，1是恶性肿瘤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = np.array(raw_data_X)\n",
    "y_train = np.array(raw_data_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3.39353321, 2.33127338],\n",
       "       [3.11007348, 1.78153964],\n",
       "       [1.34380883, 3.36836095],\n",
       "       [3.58229404, 4.67917911],\n",
       "       [2.28036244, 2.86699026],\n",
       "       [7.42343694, 4.69652288],\n",
       "       [5.745052  , 3.5339898 ],\n",
       "       [9.17216862, 2.51110105],\n",
       "       [7.79278348, 3.42408894],\n",
       "       [7.93982082, 0.79163723]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_train[y_train==0,0], X_train[y_train==0,1], color='g', marker=\"+\") # X_train[y_train==0,0]表示从X_train中取y_train中等于0的索引对应的行的第0列\n",
    "plt.scatter(X_train[y_train==1,0], X_train[y_train==1,1], color='r', marker=\"*\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array([8.093607318, 3.365731514])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x[0], x[1], color=\"blue\", marker=\"o\")\n",
    "plt.scatter(X_train[y_train==0,0], X_train[y_train==0,1], color='g', marker=\"+\")\n",
    "plt.scatter(X_train[y_train==1,0], X_train[y_train==1,1], color='r', marker=\"*\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## kNN的过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([8.09360732, 3.36573151])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x # x是待预测的点，从上面图可以看出属于y_train中的1，下面来用理论证实下"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4.812566907609877,\n",
       " 5.229270827235305,\n",
       " 6.749798999160064,\n",
       " 4.6986266144110695,\n",
       " 5.83460014556857,\n",
       " 1.4900114024329525,\n",
       " 2.354574897431513,\n",
       " 1.3761132675144652,\n",
       " 0.3064319992975,\n",
       " 2.5786840957478887]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import sqrt\n",
    "distances = []\n",
    "# 求出每个点到制定点的距离，所有的距离组成距离数组distances\n",
    "for x_train in X_train:\n",
    "    d = sqrt(np.sum((x_train - x)**2)) # np.sum默认沿着行方向(axis=0)，每行算一个点去求和\n",
    "    distances.append(d)\n",
    "distances"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([8, 7, 5, 6, 9, 3, 0, 1, 4, 2], dtype=int64)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argsort(distances) # 排序后返回元素的索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([8, 7, 5, 6, 9, 3, 0, 1, 4, 2], dtype=int64)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nearest = np.argsort(distances) # 排序后返回元素的索引\n",
    "nearest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "k = 6 # K近邻算法，取最近的6个点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "topK_y = [y_train[i] for i in nearest[:k]]  # 取最近的k个点的下表，对应着去y_train中把指定下标的元素取出来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 1, 1, 1, 1, 0]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "topK_y  # 最近的6个点，5个对应的结果都是同一类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Counter({1: 5, 0: 1})"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 下面对topk_y中的元素分布做一下统计\n",
    "from collections import Counter\n",
    "Counter(topK_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "votes = Counter(topK_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1, 5), (0, 1)]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "votes.most_common(2) # 找出票数最多的n个元素，2就是n的具体值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1, 5)]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "votes.most_common(1) # 找出票数最多的n个元素，1就是n的具体值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "predict_y = votes.most_common(1)[0][0]  # 注意取出具体的预测的值的方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    }
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
